<?php


namespace app\controllers;

use app\exception\ErrorCode;
use app\models\UserDto;
use app\exception\OaException;
use app\utils\JwtUtil;
use Firebase\JWT\ExpiredException;
use yii\base\Model;
use yii\helpers\Json;
use yii\web\Controller;

abstract class BaseJsonController extends Controller
{
    public $enableCsrfValidation = false;

    /**
     * @return Model
     */
    protected function injectionReq()
    {
        return null;
    }

    /**
     * @param $request
     * @return Model|null
     * @throws OaException
     */
    public function resolveReq($request) {




        $reqClass = $this->injectionReq();
        if ($reqClass == null) return null;
        $reqClass->attributes = $request;
        $reqClass->validate();
        if ($reqClass->hasErrors()) {
            foreach ($reqClass->getFirstErrors() as $k=>$v) {
                throw new OaException(ErrorCode::PARMA_ERROR);
            }
        }
        return $reqClass;
    }

    /**
     * @return string
     */
    public function actionIndex() {
        $headers = \Yii::$app->request->getHeaders();
        $token = isset($headers["authorization"])?$headers["authorization"]:"";
        $post = @file_get_contents('php://input');
        $request = Json::decode($post);

        try {
            $userInfo = new UserDto();
            if ($this->needLogin()) {
                if (!$token) throw new OaException(ErrorCode::TOKEN_ERR);



                try {
                    $jwtDecode = JwtUtil::decode($token, \Yii::$app->params["jwtKey"]);


                    $userInfo->setId($jwtDecode->data->id);
                    $userInfo->setPerms(json_decode(json_encode($jwtDecode->data->perms),true));
                } catch (ExpiredException $e) {
                    throw new OaException(ErrorCode::Expired_token);
                } catch (\Exception $e) {
                    throw new OaException(ErrorCode::TOKEN_ERR);
                }
            }

            if ($this->permissionName()!=null) {
                if (!in_array($this->permissionName(),$userInfo->getPerms())) {
                    throw new OaException(ErrorCode::NO_POWER);
                }
            }

            $req = $this->resolveReq($request);
            $resp["data"] = $this->doService($req,$userInfo);
            $resp["code"] = 200;

        } catch (OaException $e) {
            $resp["code"] = $e->getCode();
            $resp["msg"] = $e->getMessage();
        } catch (\Throwable $e) {
            $resp["code"] = -1;
            $resp["msg"] = ErrorCode::SYS_ERROR[-1];
            $resp["msg"] = ["-1" =>$e->getMessage()];
            \Yii::error("error code is ".$e->getCode()." msg is ".$e->getMessage());
        }
        return Json::encode($resp);
    }

    /**
     * @param $req
     * @param $userInfo
     * @return mixed
     */
    public abstract function doService($req,$userInfo);

    /**
     * @return bool
     */
    public function needLogin(){
        return true;
    }

    protected function permissionName(){
        return null;
    }
}